package org.dmcs.homework.statistics.implementations;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.dmcs.homework.statistics.CollectionPrinter;
import org.dmcs.homework.statistics.api.ICombinationsGenerator;
import org.paukov.combinatorics.CombinatoricsVector;
import org.paukov.combinatorics.Factory;
import org.paukov.combinatorics.Generator;
import org.paukov.combinatorics.ICombinatoricsVector;

/**
 * A generator for combinations.
 * @author Zielony
 * @version 1.0
 */
public class CombinationsGenerator implements ICombinationsGenerator {
	/**
	 * {@inheritDoc}
	 */
	public List<int[]> getAllCombinations(int size, int featureCount) {
		CollectionPrinter printer = new CollectionPrinter();
		
		/*
		 * Wektor zawierajacy wszystkie elementy zbioru zrodlowego.
		 */
		ICombinatoricsVector sourceVector = new CombinatoricsVector();
		
		/*
		 * Wypelnianie zbioru zrodlowego.
		 */
		for(int i=0; i<size; i++) {
			sourceVector.addValue(i);
		}
		
		/*
		 * Generowanie kombinacji przy pomocy narzedzi z biblioteki CombinatoricsLib.
		 */
		Generator<Integer> generator = Factory.<Integer>createSimpleCombinationGenerator(
				sourceVector, featureCount);
		
		List<ICombinatoricsVector<Integer>> combinations = generator.
				generateAllObjects();
		
		Iterator<ICombinatoricsVector<Integer>> combinationIterator = 
				combinations.iterator();
		
		/*
		 * Forma koncowa listy kombinacji.
		 */
		List<int[]> result = new LinkedList<int[]>();
		
		/*
		 * i-ta kombinacja w postaci int[].
		 */
		int[] iCombination;
		
		/*
		 * i-ta kombinacja jako wektor.
		 */
		ICombinatoricsVector<Integer> iCombinationVector; 
		
		/*
		 * Przepisywanie wektora do wymaganej formy końcowej.
		 */
		while(combinationIterator.hasNext()) {
			iCombinationVector = combinationIterator.next();
			
			iCombination = new int[featureCount];
			
			for(int i=0; i<iCombinationVector.getSize(); i++) {
				iCombination[i] = iCombinationVector.getValue(i);
			}
			
			result.add(iCombination);
		}
		
		return result;
	}
}
